#include <cstdio>
#include <cstring>
#include <stdexcept>

struct SimpleString {
  SimpleString(size_t max_size) : max_size{max_size}, length{} {
    if (max_size == 0) {
      throw std::runtime_error("max_size cannot be zero");
    }
    buffer = new char[max_size];
    // 目前是空字符串，所以设置第一个字符为0
    buffer[0] = 0;
  }
  ~SimpleString() { delete[] buffer; }
  // 复制构造函数
  SimpleString(const SimpleString &other)
      : max_size{other.max_size}, buffer{new char[other.max_size]},
        length{other.length} {
    std::strncpy(buffer, other.buffer, max_size);
  }
  // 复制赋值运算符
  SimpleString &operator=(const SimpleString &other) {
    if (this == &other) {
      return *this;
    }
    delete[] buffer;
    const auto new_buffer = new char[other.max_size];
    buffer = new_buffer;
    length = other.length;
    max_size = other.max_size;
    std::strncpy(new_buffer, other.buffer, other.max_size);
    return *this;
  }
  // 移动构造函数
  SimpleString(SimpleString &&other) noexcept
      : max_size{other.max_size}, buffer{other.buffer}, length{other.length} {
    other.length = 0;
    other.buffer = nullptr;
    other.max_size = 0;
  }
  // 移动赋值运算符
  SimpleString &operator=(SimpleString &&other) noexcept {
    if (this == &other) {
      return *this;
    }
    delete[] buffer;
    max_size = other.max_size;
    buffer = other.buffer;
    length = other.length;
    other.length = 0;
    other.buffer = nullptr;
    other.max_size = 0;
    return *this;
  }
  void print(const char *tag) const { printf("%s: %s", tag, buffer); }
  bool append_line(const char *x) {
    const auto x_len = strlen(x);
    // 这里 + 2 是因为换行符和 0 结尾
    if (x_len + length + 2 > max_size) {
      return false;
    }
    std::strncpy(buffer + length, x, x_len + 2);
    // 更新 length
    length += x_len;
    // 这里是写入换行符后, length 再 +1;
    buffer[length++] = '\n';
    buffer[length] = 0;
    return true;
  }

private:
  size_t max_size;
  char *buffer;
  size_t length;
};

struct SimpleStringOwner {
  SimpleStringOwner(SimpleString &&s) : string{std::move(s)} {}
  SimpleStringOwner(const char *x) : string{10} {
    if (!string.append_line(x)) {
      throw std::runtime_error("Not enough memory!");
    }
    string.print("Constructed");
  }
  ~SimpleStringOwner() { string.print("About to destruct"); }

private:
  SimpleString string;
};

int main(int argc, char **argv) {
  SimpleString a{50};
  a.append_line("We apologize for the");
  SimpleString a_copy{a};
  a.append_line("inconvenience.");
  a_copy.append_line("INCONVENIENCE.");
  a.print("a");
  a_copy.print("a_copy");

  SimpleString c{50};
  c.append_line("We apologize for the");
  SimpleString d{50};
  d.append_line("Last message");
  c.print("c");
  d.print("d");
  d = c;
  c.print("c");
  d.print("d");

  return 0;
}
